﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Redmine.Net.Api.Types;
using System.ComponentModel;

namespace RedmineWorkerDotNET.App.Classes
{
    public class ComparableIssue : IComparable
    {
        private Issue _objIssue;

        public ComparableIssue(Issue objIssue)
        {
            _objIssue = objIssue;
        }

        #region Properties

        public int Id
        {
            get { return _objIssue.Id; }
            set { _objIssue.Id = value; }
        }
        
        public IdentifiableName AssignedTo
        {
            get { return _objIssue.AssignedTo; }
            set { _objIssue.AssignedTo = value; }
        }

        public IList<Attachment> Attachments
        {
            get { return _objIssue.Attachments; }
            set { _objIssue.Attachments = value; }
        }

        public IdentifiableName Author
        {
            get { return _objIssue.Author; }
            set { _objIssue.Author = value; }
        }

        public IdentifiableName Category
        {
            get { return _objIssue.Category; }
            set { _objIssue.Category = value; }
        }

        public IList<Journal> Changesets
        {
            get { return _objIssue.Changesets; }
            set { _objIssue.Changesets = value; }
        }

        public DateTime? CreatedOn
        {
            get { return _objIssue.CreatedOn; }
            set { _objIssue.CreatedOn = value; }
        }

        public IList<CustomField> CustomFields
        {
            get { return _objIssue.CustomFields; }
            set { _objIssue.CustomFields = value; }
        }

        public string Description
        {
            get { return _objIssue.Description; }
            set { _objIssue.Description = value; }
        }

        public float? DoneRatio
        {
            get { return _objIssue.DoneRatio; }
            set { _objIssue.DoneRatio = value; }
        }

        public DateTime? DueDate
        {
            get { return _objIssue.DueDate; }
            set { _objIssue.DueDate = value; }
        }

        public float? EstimatedHours
        {
            get { return _objIssue.EstimatedHours; }
            set { _objIssue.EstimatedHours = value; }
        }

        public IdentifiableName FixedVersion
        {
            get { return _objIssue.FixedVersion; }
            set { _objIssue.FixedVersion = value; }
        }

        public IList<Journal> Journals
        {
            get { return _objIssue.Journals; }
            set { _objIssue.Journals = value; }
        }

        public IdentifiableName Priority
        {
            get { return _objIssue.Priority; }
            set { _objIssue.Priority = value; }
        }

        public ComparableIdentifiable Project
        {
            get { return new ComparableIdentifiable(_objIssue.Project); }
            set { _objIssue.Project = value.Original; }
        }

        public IList<IssueRelation> Relations
        {
            get { return _objIssue.Relations; }
            set { _objIssue.Relations = value; }
        }

        public DateTime? StartDate
        {
            get { return _objIssue.StartDate; }
            set { _objIssue.StartDate = value; }
        }

        public ComparableIdentifiable Parent
        {
            get { return _objIssue.Parent != null ? new ComparableIdentifiable(_objIssue.Parent) : null; }
            set { _objIssue.Parent = value != null ? value.Original : null; }
        }

        public ComparableIdentifiable Status
        {
            get { return new ComparableIdentifiable(_objIssue.Status); }
            set { _objIssue.Status = value.Original; }
        }

        public string Subject
        {
            get { return _objIssue.Subject; }
            set { _objIssue.Subject = value; }
        }

        public IdentifiableName Tracker
        {
            get { return _objIssue.Tracker; }
            set { _objIssue.Tracker = value; }
        }

        public DateTime? UpdatedOn
        {
            get { return _objIssue.UpdatedOn; }
            set { _objIssue.UpdatedOn = value; }
        }

        public Issue Original
        {
            get { return _objIssue; }
        }

        public override string ToString()
        {
            return _objIssue.ToString();
        }
        
        #endregion

        public int CompareTo(object obj)
        {
            return _objIssue.Id.CompareTo((obj as ComparableIssue).Id);
        }

        public override bool Equals(object obj)
        {
            return _objIssue.Id.Equals((obj as ComparableIssue).Id);
        }
    }

    [TypeConverter(typeof(ComparableIdentifiableTypeConverter))]
    public class ComparableIdentifiable : IComparable
    {
        private IdentifiableName _objIdentifiable;

        public ComparableIdentifiable(IdentifiableName objIdentifiable)
        {
            _objIdentifiable = objIdentifiable;
        }

        public string Name
        {
            get { return _objIdentifiable.Name; }
            set { _objIdentifiable.Name = value; }
        }  

        public int Id
        {
            get { return _objIdentifiable.Id; }
            set { _objIdentifiable.Id = value; }
        }

        public IdentifiableName Original
        {
            get { return _objIdentifiable; }
        }

        public int CompareTo(object obj)
        {
            return _objIdentifiable.Name.CompareTo((obj as ComparableIdentifiable).Name);
        }

        public override bool Equals(object obj)
        {
            if (obj is ComparableIdentifiable)
                return _objIdentifiable.Id.Equals((obj as ComparableIdentifiable).Id);
            return false;
        }

        public override string ToString()
        {
            return _objIdentifiable.ToString();
        }
    }
}
